package com.yanqu.road.server.manger.activity.sonhai;

import com.alibaba.fastjson.JSONObject;
import com.github.houbb.heaven.util.util.DateUtil;
import com.yanqu.road.dao.impl.activity.sonhai.SonHaiConfigDaoImpl;
import com.yanqu.road.dao.impl.config.PatronsDaoImpl;
import com.yanqu.road.dao.impl.player.UserPatronsDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.commonteam.CommonTeamConfigData;
import com.yanqu.road.entity.activity.hsisland.config.HsIslandConfig;
import com.yanqu.road.entity.activity.sonhai.config.*;
import com.yanqu.road.entity.activity.sonhai.data.SonHaiPatronsData;
import com.yanqu.road.entity.activity.sonhai.data.SonHaiVipPowerData;
import com.yanqu.road.entity.activity.sonhai.enums.SonHaiEnergyPropEnum;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eMailType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.exception.BusinessException;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.SonHaiProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.goodsLimit.GoodsLimitModule;
import com.yanqu.road.server.gameplayer.module.activity.sonhai.SonHaiActivityModule;
import com.yanqu.road.server.gameplayer.module.patrons.CombLeaderModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.PreReduceModule;
import com.yanqu.road.server.gameplayer.module.useract.UserActModule;
import com.yanqu.road.server.gameplayer.module.vehicle.VehicleModule;
import com.yanqu.road.server.logic.mail.MailManager;
import com.yanqu.road.server.manger.MultipleLanguageMgr;
import com.yanqu.road.server.manger.VipMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.commonteam.CommonTeamMgr;
import com.yanqu.road.server.manger.activity.douluodalu.DouLuoDaLuMgr;
import com.yanqu.road.server.manger.activity.dunhuangshiku.DunHuangShiKuMgr;
import com.yanqu.road.server.manger.activity.hsisland.HsIslandActivityMgr;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.config.PatronsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.ListHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class SonHaiActivityMgr extends TempMgr {

    /**
     * logger
     */
    private static Logger logger = LogManager.getLogger(SonHaiActivityMgr.class.getName());

    /**
     * 活动配置Map
     */
    private static Map<Integer, SonHaiConfig> activityConfigMap = new ConcurrentHashMap<>();

    @Override
    public boolean init() throws Exception {
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static SonHaiConfig getSonHaiConfig(int activityId) {
        return activityConfigMap.get(activityId);
    }

    public static Map<Integer, SonHaiConfig> getActivityConfigMap() {
        return activityConfigMap;
    }

    /**
     * 加载活动
     */
    public static void reloadActivityData() {
        getLogger().info("reload SonHaiActivityMgr start");
        //获取开启中的活动
        List<ActivityInfo> list = NormalActivityMgr.getOpenActivityInfoList(eActivityType.SonHai.getValue());
        //创建活动配置Map
        Map<Integer, SonHaiConfig> sonHaiConfigMap = new ConcurrentHashMap<>();
        for (ActivityInfo activityInfo : list) {
            //获取活动config
            Map<String, ActivityConfig> configMap = NormalActivityMgr.getActivityConfigMap(activityInfo.getActivityId());
            //mall map
            Map<Integer, MallInfo> mallInfoMap = NormalActivityMgr.getActivityMallInfoMap(activityInfo.getActivityId());
            //事件配置
            SonHaiConfigDaoImpl dao = new SonHaiConfigDaoImpl();
            Map<Integer, SonHaiEventConfig> eventConfigMap = dao.getEventConfigMap(activityInfo.getActivityId());
            //区域配置
            Map<Integer, SonHaiFloorConfig> floorConfigMap = dao.getFloorConfigMap(activityInfo.getActivityId());
            //BUFF配置
            Map<Integer, SonHaiBuffConfig> buffConfigMap = dao.getBuffConfigMap(activityInfo.getActivityId());
            //怪配置
            Map<Integer, SonHaiMonsterConfig> monsterConfigMap = dao.getMonsterConfigMap(activityInfo.getActivityId());
            //蛋配置
            Map<Integer, SonHaiEggConfig> eggConfigMap = dao.getEggConfigMap(activityInfo.getActivityId());
            //地图配置
            Map<Integer, SonHaiMapConfig> mapConfigMap = dao.getMapConfigMap(activityInfo.getActivityId());
            //蛋名配置
            Map<Integer, SonHaiEggNameConfig> eggNameConfigMap = dao.getEggNameConfigMap(activityInfo.getActivityId());
            //创建活动config对象
            SonHaiConfig sonHaiConfig = new SonHaiConfig(activityInfo, configMap, mallInfoMap, eventConfigMap, floorConfigMap, buffConfigMap, monsterConfigMap, eggConfigMap, mapConfigMap, eggNameConfigMap);
            sonHaiConfigMap.put(activityInfo.getActivityId(), sonHaiConfig);
        }
        activityConfigMap = sonHaiConfigMap;
        //在线玩家,同步下活动数据
        List<GamePlayer> gamePlayerList = GamePlayerMgr.getAllOnlinePlayer();
        for (GamePlayer gamePlayer : gamePlayerList) {
            //同步活动配置，判断系统是是否解锁
            if (SystemOpenMgr.systemOpen(gamePlayer, eSystemId.SonHai.getValue())) {
                gamePlayer.getModule(SonHaiActivityModule.class).syncConfig();
            }
        }
        getLogger().info("reload SonHaiActivityMgr end");
    }

    /**
     * 公用check
     * @param gamePlayer
     * @param activityId
     * @param checkInTime
     * @throws BusinessException
     */
    private static void commonCheck(GamePlayer gamePlayer, int activityId, boolean checkInTime) throws BusinessException {
        //活动是否存在
        ActivityInfo activityInfo = ActivityMgr.getOpenActivityInfo(activityId);
        if (activityInfo == null) {
            throw new BusinessException(GameErrorCode.E_ACTIVITY_NO_FOUND);
        }
        //活动配置
        SonHaiConfig sonHaiConfig = activityConfigMap.get(activityId);
        if (sonHaiConfig == null) {
            throw new BusinessException(GameErrorCode.E_SON_HAI_ACTIVITY_NOT_FOUND);
        }
        //判断是否在活动展示期
        if (!ActivityHelper.activityInShowTime(activityInfo)) {
            throw BusinessException.newException(GameErrorCode.E_SON_HAI_ACTIVITY_NOT_IN_SHOW_TIME);
        }
        //判断是否在活动进行期
        if (checkInTime && !ActivityHelper.activityInTime(activityInfo)) {
            throw BusinessException.newException(GameErrorCode.E_SON_HAI_ACTIVITY_NOT_IN_TIME);
        }
        //判断是否不在组队期
        boolean isInTeamTime = CommonTeamMgr.checkInTeamTime(activityId);
        if (isInTeamTime) {
            throw BusinessException.newException(GameErrorCode.E_SON_HAI_ACTIVITY_IN_TEAM_TIME);
        }
        //系统是否解锁
        if (!SystemOpenMgr.checkSystemOpen(gamePlayer.getUserId(), eSystemId.SonHai.getValue())) {
            throw BusinessException.newException(GameErrorCode.E_SYSTEM_NO_OPEN);
        }
    }

    /**
     * 进入活动
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void enterActivity(GamePlayer gamePlayer, SonHaiProto.SonHaiEnterActivityReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        gamePlayer.getModule(SonHaiActivityModule.class).enterActivity(reqMsg.getActivityId());
    }

    /**
     * 探索
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void explore(GamePlayer gamePlayer, SonHaiProto.SonHaiExploreReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_EXPLORE, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_EXPLORE, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 获取地块详情
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void getPlotDetail(GamePlayer gamePlayer, SonHaiProto.SonHaiGetPlotDetailReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_GET_PLOT_DETAIL, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_GET_PLOT_DETAIL, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 战斗-PVE
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void battlePve(GamePlayer gamePlayer, SonHaiProto.SonHaiBattlePveReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_BATTLE_PVE, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_BATTLE_PVE, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 战斗-PVP
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void battlePvp(GamePlayer gamePlayer, SonHaiProto.SonHaiBattlePvpReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_BATTLE_PVP, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_BATTLE_PVP, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 战斗-BOSS
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void battleBoss(GamePlayer gamePlayer, SonHaiProto.SonHaiBattleBossReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_BATTLE_BOSS, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_BATTLE_BOSS, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 战斗-EGG
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void battleEgg(GamePlayer gamePlayer, SonHaiProto.SonHaiBattleEggReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        SonHaiProto.SonHaiCrossBattleEggReqMsg.Builder reqMsgBuilder = SonHaiProto.SonHaiCrossBattleEggReqMsg.newBuilder();
        reqMsgBuilder.setActivityId(reqMsg.getActivityId());
        reqMsgBuilder.setX(reqMsg.getX());
        reqMsgBuilder.setY(reqMsg.getY());
        reqMsgBuilder.setRegionId(reqMsg.getRegionId());
        reqMsgBuilder.addAllPatronsIds(reqMsg.getPatronsIdsList());
        //获取玩家门客
        for (int patronsId : reqMsg.getPatronsIdsList()) {
            //获取门客
            UserPatrons userPatrons = gamePlayer.getModule(PatronsModule.class).getUserPatrons(patronsId);
            if (userPatrons == null) {
                throw new BusinessException(GameErrorCode.E_PATRONS_NO_FOUND);
            }
            //获取门客配置
            PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userPatrons.getPatronsId());
            if (patronsInfo == null) {
                throw new BusinessException(GameErrorCode.E_PATRONS_NO_FOUND);
            }
            //获取品质
            int quality = PatronsMgr.getPatronsQuality(userPatrons);
            SonHaiProto.SonHaiPatronsData.Builder patronBuilder = SonHaiProto.SonHaiPatronsData.newBuilder();
            patronBuilder.setPatronsId(userPatrons.getPatronsId());
            patronBuilder.setOccupation(patronsInfo.getOccupation());
            patronBuilder.setBasePower(userPatrons.getAbility().longValue());
            patronBuilder.setQuality(quality);
            patronBuilder.setSkinId(userPatrons.getSkinId());
            patronBuilder.setIsLinkageSwitch(userPatrons.isLinkageSwitch());
            reqMsgBuilder.addPatronsDataList(patronBuilder);
        }
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_BATTLE_EGG, reqMsgBuilder);
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_BATTLE_EGG, reqMsgBuilder, reqMsgBuilder.getActivityId());
    }

    /**
     * 获取驻守在兽蛋的门客
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void getInEggPatrons(GamePlayer gamePlayer, SonHaiProto.SonHaiGetInEggPatronsReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), false);
        //上跨服
        SonHaiProto.SonHaiGetInEggPatronsReqMsg.Builder reqMsgBuilder = reqMsg.toBuilder();
        reqMsgBuilder.setLanguage(gamePlayer.getLanguage());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_GET_IN_EGG_PATRONS, reqMsgBuilder, reqMsgBuilder.getActivityId());
    }

    /**
     * 获取兽蛋LIST
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void getGetEggList(GamePlayer gamePlayer, SonHaiProto.SonHaiGetEggListReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), false);
        //上跨服
        SonHaiProto.SonHaiGetEggListReqMsg.Builder reqMsgBuilder = reqMsg.toBuilder();
        reqMsgBuilder.setLanguage(gamePlayer.getLanguage());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_GET_EGG_LIST, reqMsgBuilder, reqMsgBuilder.getActivityId());
    }

    /**
     * 获取兽蛋奖励LIST
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void getGetEggRewardList(GamePlayer gamePlayer, SonHaiProto.SonHaiGetEggRewardListReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), false);
        //上跨服
        SonHaiProto.SonHaiGetEggRewardListReqMsg.Builder reqMsgBuilder = reqMsg.toBuilder();
        reqMsgBuilder.setLanguage(gamePlayer.getLanguage());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_GET_EGG_REWARD_LIST, reqMsgBuilder, reqMsgBuilder.getActivityId());
    }

    /**
     * 领取兽蛋孵化奖励
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void receiveEggReward(GamePlayer gamePlayer, SonHaiProto.SonHaiReceiveEggRewardReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), false);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_RECEIVE_EGG_REWARD, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_RECEIVE_EGG_REWARD, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 离开区域，进入其他区域
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void enterRegion(GamePlayer gamePlayer, SonHaiProto.SonHaiEnterRegionReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_ENTER_REGION, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_ENTER_REGION, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 重置区域
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void resetRegion(GamePlayer gamePlayer, SonHaiProto.SonHaiResetRegionReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_RESET_REGION, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_RESET_REGION, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 选择BUFF
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void selectBuff(GamePlayer gamePlayer, SonHaiProto.SonHaiSelectBuffReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_SELECT_BUFF, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_SELECT_BUFF, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 获取日志列表
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void getLogList(GamePlayer gamePlayer, SonHaiProto.SonHaiBattleLogReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_GET_LOG_LIST, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_GET_LOG_LIST, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 领取日志奖励
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void receiveLogReward(GamePlayer gamePlayer, SonHaiProto.SonHaiReceiveLogRewardReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_RECEIVE_LOG_REWARD, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_RECEIVE_LOG_REWARD, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 消耗道具恢复体力
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void usePropRecoverEnergy(GamePlayer gamePlayer, SonHaiProto.SonHaiUsePropRecoverEnergyReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //判断道具ID是否正确
        if (!SonHaiEnergyPropEnum.checkPropId(reqMsg.getPropId())) {
            throw new BusinessException(GameErrorCode.E_SON_HAI_ENERGY_PROP_ID_ERROR);
        }
        if (reqMsg.getNum() <= 0) {
            throw new BusinessException(GameErrorCode.E_SON_HAI_ENERGY_PROP_NUM_ERROR);
        }
        //判断道具是否存在
        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(reqMsg.getPropId());
        if (goodsInfo == null) {
            throw new BusinessException(GameErrorCode.E_GOODS_NO_EXIST);
        }
        Property property = new Property(reqMsg.getPropId(), reqMsg.getNum());
        //判断道具是否足够
        if (!gamePlayer.getModule(CurrencyModule.class).currencyIsEnough(property)) {
            throw new BusinessException(GameErrorCode.E_SON_HAI_PROP_NOT_ENOUGH);
        }
        //判断道具是否达到使用上限
        long goodsUseCount = gamePlayer.getModule(GoodsLimitModule.class).getGoodsUseCount(reqMsg.getPropId(), reqMsg.getActivityId());
        SonHaiConfig sonHaiConfig = getSonHaiConfig(reqMsg.getActivityId());
        boolean limitFlag = sonHaiConfig.checkEnergyPropUseLimit(reqMsg.getPropId(), goodsUseCount + reqMsg.getNum());
        if (!limitFlag) {
            throw new BusinessException(GameErrorCode.E_BAG_USE_GOODS_LIMIT);
        }
        //预扣道具
        gamePlayer.getModule(PreReduceModule.class).preReduce(property);
        //上跨服
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_USE_PROP_RECOVER_ENERGY, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 获取区域LIST
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void getRegionList(GamePlayer gamePlayer, SonHaiProto.SonHaiGetRegionListReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), false);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_GET_REGION_LIST, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_GET_REGION_LIST, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 获取战斗日志LIST
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void getBattleLogList(GamePlayer gamePlayer, SonHaiProto.SonHaiGetBattleLogListReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), false);
        //上跨服
        SonHaiProto.SonHaiGetBattleLogListReqMsg.Builder reqMsgBuilder = reqMsg.toBuilder();
        reqMsgBuilder.setLanguage(gamePlayer.getLanguage());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_GET_BATTLE_LOG_LIST, reqMsgBuilder, reqMsgBuilder.getActivityId());
    }

    /**
     * 唤醒
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void wakeUp(GamePlayer gamePlayer, SonHaiProto.SonHaiWakeUpReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
//        gamePlayer.sendPacket(Protocol.C2_SON_HAI_WAKE_UP, reqMsg.toBuilder());
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_WAKE_UP, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 重新随机待选择BUFF列表
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void resetRandomSelectBuff(GamePlayer gamePlayer, SonHaiProto.SonHaiResetRandomSelectBuffListReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //判断元宝是否足够
        SonHaiConfig sonHaiConfig = activityConfigMap.get(reqMsg.getActivityId());
        int costNum = sonHaiConfig.getResetRandomWaitBuffListCost();
        Property cost = new Property(GameConfig.GAME_MONEY_INGOTS, costNum);
        if (!gamePlayer.getModule(CurrencyModule.class).currencyIsEnough(cost)) {
            throw new BusinessException(GameErrorCode.E_SON_HAI_PROP_NOT_ENOUGH);
        }
        //预扣
        gamePlayer.getModule(PreReduceModule.class).preReduce(cost);
        //上跨服
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_RESET_RANDOM_SELECT_BUFF_LIST, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 2选1，选择奖励
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void receiveChooseReward(GamePlayer gamePlayer, SonHaiProto.SonHaiReceiveChooseRewardReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_RECEIVE_CHOOSE_REWARD, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 接收到占领的蛋被抢推送消息
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void acceptOccupyEggBeTakenMsg(GamePlayer gamePlayer, SonHaiProto.SonHaiAcceptOccupyEggBeTakenMsgReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_ACCEPT_OCCUPY_EGG_BE_TAKEN_MSG, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /**
     * 同意/拒绝重置区域
     * @param gamePlayer
     * @param reqMsg
     * @throws BusinessException
     */
    public static void opRestRegion(GamePlayer gamePlayer, SonHaiProto.SonHaiOpRestRegionReqMsg reqMsg) throws BusinessException {
        commonCheck(gamePlayer, reqMsg.getActivityId(), true);
        //上跨服
        gamePlayer.sendUnionActivityGroupPacket(Protocol.C2_SON_HAI_OP_REST_REGION, reqMsg.toBuilder(), reqMsg.getActivityId());
    }

    /***************************************跨服返回************************************************/

    /**
     * 探索-跨服返回
     * @param gamePlayer
     * @param respMsg
     * @throws BusinessException
     */
    public static void exploreFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiExploreRespMsg respMsg) {
        gamePlayer.getModule(SonHaiActivityModule.class).exploreFromCross(respMsg);
    }

    /**
     * 战斗PVE-跨服返回
     * @param gamePlayer
     * @param respMsg
     * @throws BusinessException
     */
    public static void battlePveFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiBattlePveRespMsg respMsg) {
        if (respMsg.hasBattleResult() && respMsg.getBattleResult().hasReward() && !StringUtils.isNullOrEmpty(respMsg.getBattleResult().getReward())) {
            String rewardStr = respMsg.getBattleResult().getReward();
            Property reward = PropertyHelper.parseStringToProperty(rewardStr);
            //添加奖励
            gamePlayer.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiBattlePveWinReward);
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_BATTLE_PVE, respMsg.toBuilder());
    }

    /**
     * 战斗PVP-跨服返回
     * @param gamePlayer
     * @param respMsg
     * @throws BusinessException
     */
    public static void battlePvpFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiBattlePvpRespMsg respMsg) {
        if (respMsg.hasBattleResult() && respMsg.getBattleResult().hasReward() && !StringUtils.isNullOrEmpty(respMsg.getBattleResult().getReward())) {
            String rewardStr = respMsg.getBattleResult().getReward();
            Property reward = PropertyHelper.parseStringToProperty(rewardStr);
            //添加奖励
            gamePlayer.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiBattlePvpWinReward);
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_BATTLE_PVP, respMsg.toBuilder());
    }

    /**
     * 战斗BOSS-跨服返回
     * @param gamePlayer
     * @param respMsg
     * @throws BusinessException
     */
    public static void battleBossFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiBattleBossRespMsg respMsg) {
        if (respMsg.hasBattleResult() && respMsg.getBattleResult().hasReward() && !StringUtils.isNullOrEmpty(respMsg.getBattleResult().getReward())) {
            String rewardStr = respMsg.getBattleResult().getReward();
            Property reward = PropertyHelper.parseStringToProperty(rewardStr);
            //添加奖励
            gamePlayer.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiBattleBossWinReward);
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_BATTLE_BOSS, respMsg.toBuilder());
    }

    /**
     * 战斗EGG-跨服返回
     * @param gamePlayer
     * @param respMsg
     * @throws BusinessException
     */
    public static void battleEggFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiBattleEggRespMsg respMsg) {
        if (respMsg.hasReward() && !StringUtils.isNullOrEmpty(respMsg.getReward())) {
            Property reward = PropertyHelper.parseStringToProperty(respMsg.getReward());
            //添加奖励
            gamePlayer.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiBattleEggWinReward);
        }
        //门客绑定珍兽/蛐蛐/鱼
        for (int patronsId : respMsg.getPatronsIdsList()) {
            gamePlayer.getModule(VehicleModule.class).bindPatrons(patronsId, respMsg.getActivityId());
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_BATTLE_EGG, respMsg.toBuilder());
    }

    /**
     * 领取兽蛋孵化奖励-跨服返回
     * @param gamePlayer
     * @param respMsg
     * @throws BusinessException
     */
    public static void receiveEggRewardFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiReceiveEggRewardRespMsg respMsg) {
        if (respMsg.hasReward() && !StringUtils.isNullOrEmpty(respMsg.getReward())) {
            Property reward = PropertyHelper.parseStringToProperty(respMsg.getReward());
            //添加奖励
            gamePlayer.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiReceiveEggReward);
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_RECEIVE_EGG_REWARD, respMsg.toBuilder());
    }

    /**
     * 区域消失，未领取奖励邮件发送-跨服返回
     * @param userId
     * @param respMsg
     * @throws BusinessException
     */
    public static void sendRegionResetRewardFromCross(long userId, SonHaiProto.SonHaiSendRegionResetRewardMsg respMsg) {
        if (respMsg.hasReward() && !StringUtils.isNullOrEmpty(respMsg.getReward())) {
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            if (userInfo == null) {
                logger.error("山海伏兽-区域消失，未领取奖励邮件发送-玩家不存在：{},{}", userId, respMsg.getReward());
                return;
            }
            String reward = respMsg.getReward();
            //邮件发送奖励
            String mailTitle = MultipleLanguageMgr.getContent(MailManager.SON_HAI_REGION_RESET_REWARD_TITLE, userInfo.getLanguage());
            String mailContent = MultipleLanguageMgr.getContent(MailManager.SON_HAI_REGION_RESET_REWARD_CONTENT, userInfo.getLanguage());
            MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), reward, mailContent, mailTitle);
        }
    }

    /**
     * 领取日志奖励-跨服返回
     * @param gamePlayer
     * @param respMsg
     */
    public static void receiveLogRewardFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiReceiveLogRewardRespMsg respMsg) {
        if (respMsg.hasReward() && !StringUtils.isNullOrEmpty(respMsg.getReward())) {
            Property reward = PropertyHelper.parseStringToProperty(respMsg.getReward());
            //添加奖励
            gamePlayer.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiReceiveLogReward);
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_RECEIVE_LOG_REWARD, respMsg.toBuilder());
    }

    /**
     * 使用道具恢复体力-跨服返回
     * @param gamePlayer
     * @param respMsg
     */
    public static void usePropRecoverEnergyFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiUsePropRecoverEnergyRespMsg respMsg) {
        Property property = new Property(respMsg.getPropId(), respMsg.getNum());
        //清理预扣除
        gamePlayer.getModule(PreReduceModule.class).restorePreReduce(property);
        if (respMsg.getRet() == 0) {
            //扣除道具
            gamePlayer.getModule(CurrencyModule.class).removeCurrency(property, eLogMoneyType.SonHai, eLogMoneyType.SonHaiUsePropRecoverEnergyCost);
            //记录道具使用数量
            gamePlayer.getModule(GoodsLimitModule.class).updateGoodsUseCount(respMsg.getPropId(), respMsg.getActivityId(), respMsg.getNum());
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_USE_PROP_RECOVER_ENERGY, respMsg.toBuilder());
    }

    public static void test() {
        //前n天活跃
        long activeTime = DateHelper.getTimestampForDaysBefore(3);
        //k:vipLevel,k:第几赚钱门客
        Map<Integer, Map<Integer, SonHaiVipPowerData>> vipPowerDataMap = new HashMap<>();
        for (UserInfo userInfo : UserMgr.getUserInfoMap().values()) {
            //前n天活跃玩家
            if (userInfo.getLastLoginTime() * 1000 >= activeTime) {
                //玩家不在线，读库
                List<UserPatrons> partonsList = new UserPatronsDaoImpl().getTopNUserPatronsList(userInfo.getUserId(), 30);
                int vipLevel = VipMgr.getVipLv(userInfo.getVipExp());
                Map<Integer, SonHaiVipPowerData> indexMap = vipPowerDataMap.computeIfAbsent(vipLevel, k -> new LinkedHashMap<>());
                System.out.println("userId:" + userInfo.getUserId());
                for (int i = 0; i < partonsList.size(); i++) {
                    SonHaiVipPowerData data = indexMap.computeIfAbsent(i, k -> new SonHaiVipPowerData(vipLevel, 0, 0));
                    data.setPower(data.getPower() + partonsList.get(i).getAbility().longValue());
                    data.setNum(data.getNum() + 1);
                }
            }
        }
        for (Map.Entry<Integer, Map<Integer, SonHaiVipPowerData>> vipEntry : vipPowerDataMap.entrySet()) {
            int vipLevel = vipEntry.getKey();
            Map<Integer, SonHaiVipPowerData> vipMap = vipEntry.getValue();
            for (Map.Entry<Integer, SonHaiVipPowerData> entry : vipMap.entrySet()) {
                int index = entry.getKey();
                SonHaiVipPowerData data = entry.getValue();
                System.out.println("vip_" + vipLevel + "。第" + index + "门客赚钱均值" + data.getPower() / data.getNum());
            }
        }
    }

    /**
     * 上报vip战力分布给跨服。
     * @param reqMsg
     */
    public static void sendVipAveToCross(SonHaiProto.SonHaiNotifyServerSyncVipPowerFromCrossMsg reqMsg) {
        //活动配置
        SonHaiConfig sonHaiConfig = activityConfigMap.get(reqMsg.getActivityId());
        if (sonHaiConfig == null) {
            logger.error("山海伏兽-上报vip均值给跨服-活动配置未找到:{}", reqMsg.getActivityId());
            return;
        }
        //前n天活跃
        int day = sonHaiConfig.getMonsterPowerDay();
        long activeTime = DateHelper.getTimestampForDaysBefore(day);
        //获取vip分级战力，k:vip等级，v：均值总和
        Map<Integer, SonHaiVipPowerData> vipPowerDataMap = new HashMap<>();
        for (UserInfo userInfo : UserMgr.getUserInfoMap().values()) {
            //前n天活跃玩家
            if (userInfo.getLastLoginTime() * 1000 >= activeTime) {
                //前30门客赚钱均值
                long aveAbility = getTop30PatronsAveAbility(userInfo.getUserId(), sonHaiConfig);
                if (aveAbility > 0) {
                    int vipLevel = VipMgr.getVipLv(userInfo.getVipExp());
                    SonHaiVipPowerData powerData = vipPowerDataMap.computeIfAbsent(vipLevel, k -> new SonHaiVipPowerData(vipLevel, 0, 0));
                    powerData.setNum(powerData.getNum() + 1);
                    powerData.setPower(powerData.getPower() + aveAbility);
                }
            }
        }
        SonHaiProto.SonHaiCrossNotifyVipPowerReqMsg.Builder builder = SonHaiProto.SonHaiCrossNotifyVipPowerReqMsg.newBuilder();
        builder.setActivityId(reqMsg.getActivityId());
        builder.setGroupId(reqMsg.getGroupId());
        for (SonHaiVipPowerData powerData : vipPowerDataMap.values()) {
            //计算一下战力均值
            long avePower = powerData.getPower() / powerData.getNum();
            SonHaiProto.SonHaiVipNumPowerData.Builder vipNumPowerDataBuilder = SonHaiProto.SonHaiVipNumPowerData.newBuilder();
            vipNumPowerDataBuilder.setVipLevel(powerData.getVipLevel());
            vipNumPowerDataBuilder.setAveAPower(avePower);
            builder.addVipPowerData(vipNumPowerDataBuilder);
        }
        logger.info("山海伏兽-上报vip均值给跨服-start:{}, {}", reqMsg.getActivityId(), JSONObject.toJSONString(vipPowerDataMap));
        //同步给跨服
        GamePlayerMgr.sendUnionActivityGroupPacket(CrossProtocol.C2_SON_HAI_SERVER_SEND_VIP_AVE_TO_CROSS, builder, 0, reqMsg.getActivityId(), reqMsg.getGroupId());
        logger.info("山海伏兽-上报vip均值给跨服-end:{}", reqMsg.getActivityId());
    }

    /**
     * 获取玩家前5门客战力均值
     * @param userId
     * @return
     */
    private static long getTop30PatronsAveAbility(long userId, SonHaiConfig sonHaiConfig) {
        GamePlayer gamePlayer = GamePlayerMgr.getOnlinePlayer(userId);
        List<UserPatrons> partonsList;
        if (gamePlayer != null) {
            //玩家在线
            partonsList = gamePlayer.getModule(PatronsModule.class).getTopAbilityPatrons(30);
        } else {
            //玩家不在线，读库
            partonsList = new UserPatronsDaoImpl().getTopNUserPatronsList(userId, 30);
        }
        if (partonsList == null || partonsList.isEmpty()) {
            return 0;
        }
        long totalPower = 0;
        for (UserPatrons userPatrons : partonsList) {
            //通过公式计算战力
            long power = sonHaiConfig.transformPatronsPower(userPatrons.getAbility().longValue());
            totalPower += power;
        }
        return totalPower / partonsList.size();
    }

    /**
     * 重新随机待选择BUFF列表-处理buff选择
     * @param gamePlayer
     * @param reqMsg
     */
    public static void resetRandomSelectBuffFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiResetRandomSelectBuffListRespMsg reqMsg) {
        //获取道具
        SonHaiConfig sonHaiConfig = activityConfigMap.get(reqMsg.getActivityId());
        int costNum = sonHaiConfig.getResetRandomWaitBuffListCost();
        Property cost = new Property(GameConfig.GAME_MONEY_INGOTS, costNum);
        //撤销预扣
        gamePlayer.getModule(PreReduceModule.class).restorePreReduce(cost);
        if (reqMsg.getRet() == 0) {
            //扣除道具
            gamePlayer.getModule(CurrencyModule.class).removeCurrency(cost, eLogMoneyType.SonHai, eLogMoneyType.SonHaiResetBuffListCost);
        }
        gamePlayer.sendPacket(Protocol.U_SON_HAI_RESET_RANDOM_SELECT_BUFF_LIST, reqMsg.toBuilder());
    }

    /**
     * 补发蛋蛋奖励-跨服返回
     * @param reqMsg
     */
    public static void bfEggRewardFromCross(SonHaiProto.SonHaiBfEggRewardFromCrossMsg reqMsg) {
        for (SonHaiProto.SonHaiBfEggRewardItem item : reqMsg.getUserEggRewardList()) {
            long userId = item.getUserId();
            String reward = item.getReward();
            UserInfo userInfo = UserMgr.getUserInfo(userId);
            if (userInfo == null) {
                logger.error("山海伏兽-补发蛋蛋奖励-玩家不存在：{},{}", userId, reward);
                return;
            }
            //邮件发送奖励
            String mailTitle = MultipleLanguageMgr.getContent(MailManager.SON_HAI_BF_EGG_REWARD_TITLE, userInfo.getLanguage());
            String mailContent = MultipleLanguageMgr.getContent(MailManager.SON_HAI_BF_EGG_REWARD_CONTENT, userInfo.getLanguage());
            MailManager.sendMail(userId, eMailType.SYSTEM.getValue(), reward, mailContent, mailTitle);
        }
    }

    /**
     * 2选1领取奖励-跨服返回
     * @param gamePlayer
     * @param respMsg
     */
    public static void receiveChooseRewardFromCross(GamePlayer gamePlayer, SonHaiProto.SonHaiReceiveChooseRewardRespMsg respMsg) {
        if (respMsg.hasReward() && !StringUtils.isNullOrEmpty(respMsg.getReward())) {
            Property reward = PropertyHelper.parseStringToProperty(respMsg.getReward());
            //添加奖励
            gamePlayer.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.SonHai, eLogMoneyType.SonHaiReceiveChooseReward);
        }
        //判断是否选择了正确选项
        SonHaiConfig config = getSonHaiConfig(respMsg.getActivityId());
        if (config != null && respMsg.hasChooseConfigId() && respMsg.getChooseConfigId() > 0) {
            if (respMsg.hasChooseTrue() && respMsg.getChooseTrue()) {
                gamePlayer.getModule(UserActModule.class).addActTrueChooseIndex(
                        config.getActivityInfo().getType(),
                        config.getActivityInfo().getChildType(),
                        String.valueOf(respMsg.getChooseConfigId()),
                        String.valueOf(respMsg.getIndex()));
            }
        }
        //回包
        gamePlayer.sendPacket(Protocol.U_SON_HAI_RECEIVE_CHOOSE_REWARD, respMsg.toBuilder());
    }
}
